跳到主要内容

Julia SciML 风格指南

理念

  • 编写尽可能宽泛的函数、尽可能广泛的测试
  • 但是,编写尽可能具体的类型
  • 编写类型稳定(从输入类型推导输出类型)和类型接地(从输入类型推导函数中的每个类型)的函数
  • 函数内部处理的类型应该和输入类型一致
  • 尽可能与 Julia 语言内部的通过多重派发实现的各种接口保持一致
  • 宏只用于语法糖,不用于实现更复杂的功能
  • 通过发布子包的方式避免条件调用模块
  • 函数尽可能是不可变的
  • 函数要么是不可变的,要么是不分配新空间的
  • 在模块中避免全局变量
  • 避免闭包,使用 Fix 等方法替代
  • 每个函数只做一件事情
  • 不要定义可能在别的地方出现的函数

具体规则

命名

  • 类型、模块用大驼峰命名法
  • 函数、变量用小蛇命名法
  • 常量用大蛇命名法
  • 类型变量用单个大写字母
  • 用完整单词而非缩写
  • 用两个下划线表明私有方法
  • 不在公开接口中使用 Unicode

注释

  • 能用命名体现的就不用注释
  • 用 TODO 和 XXX 表明没有实现的和有问题的代码
  • code 来体现代码
  • 用 URL 表示 GitHub 议题和拉取请求
  • 在代码的上面写注释,而非在行内

模块

  • 先写 import,再写 using
  • 在模块中只应该用 importusing X: x
  • 导出变量时应该尽量唯一
  • 含有模块的代码不应该含有其他东西

函数

  • 只在一行能写下的情况下用短形式
  • 没有默认值的应该作为位置参数
  • 用命名元组来批量传送关键字参数
  • 避免类型海盗:给不属于自己的类型和函数添加方法
  • 函数参数顺序
    • 函数
    • I/O
    • 被改变的输入
    • 类型
    • 没被改变的输入
    • 其他
    • 可变参数
    • 关键字

测试

  • 使用 @safetestset
  • 测试需要能够独立重现
  • CI 需要包括当前版本和 LTS

文档

  • 包括一个简短的教程,能够覆盖 90% 使用场景,展现一个完整的工作流,并且注意变量命名
  • 用 docstring 来生成 API 文档
    • 尽可能展示方法而非字段,不展示的字段不视为接口
    • 只需要展示那些导出的函数
    • 避免展示过于常见的重载函数
    • 展示一个函数而非具体的方法
    • @doc, doc"""...""" 来编写 LaTeX
    • 可以在一个 docstring 中展示多个方法,但只对自己定义的函数这么做

模板

"""
MyArray{T, N}

My super awesome array wrapper!

## Fields
- `data::AbstractArray{T, N}`: stores the array being wrapped
- `metadata::Dict`: stores metadata about the array
"""
struct MyArray{T, N} <: AbstractArray{T, N}
data::AbstractArray{T, N}
metadata::Dict
end
"""
mysearch(array::MyArray{T}, val::T; verbose = true) where {T} -> Int

Searches the `array` for the `val`. For some reason we don't want to use Julia's
builtin search :)

## Arguments
- `array::MyArray{T}`: the array to search
- `val::T`: the value to search for

## Keywords
- `verbose::Bool = true`: print out progress details

## Returns
- `Int`: the index where `val` is located in the `array`

## Throws
- `NotFoundError`: I guess we could throw an error if `val` isn't found.
"""
function mysearch(array::AbstractArray{T}, val::T) where {T}
...
end